package org.yray.sip.handler;


import io.netty.util.HashedWheelTimer;
import org.apache.commons.lang3.StringUtils;
import org.yray.sip.base.MsgEle;
import org.yray.sip.base.MsgType;
import org.yray.sip.base.RegexUtils;
import org.yray.sip.base.SipMsg;
import org.yray.sip.creator.MessageCreator;
import org.yray.sip.factory.SipSessionFactory;
import org.yray.sip.rtp.sender.ISipSessionCache;
import org.yray.sip.rtp.sender.TalkTimerTask;
import org.yray.sip.server.SipServerContext;
import org.yray.sip.server.SipSession;
import org.yray.sip.utils.IcspBeanHolder;
import org.yray.sip.utils.IdUtils;

import java.util.concurrent.TimeUnit;

public class InviteHandler extends MessageHandler {




    @Override
    public String[] handler(SipMsg sipMsg, SipServerContext ssc) {
        String[] res=new String[3];
        SipSession sipSession=new SipSession(sipMsg,ssc.getRunIp(),ssc.getRunPort(),false);
        sipSession.setSipMap(sipMsg.getSipMap());
        IcspBeanHolder.getBean(ISipSessionCache.class).put(sipMsg.getCallId(),sipSession);
        IcspBeanHolder.getBean(SipSessionFactory.class).resolvRtp(sipSession,sipMsg.getSdpList());
        IcspBeanHolder.getBean(ISipSessionCache.class).addRtcpIp(sipSession);
        IcspBeanHolder.getBean(ISipSessionCache.class).putRecvPort(sipSession.getSideRtcpIp() + sipSession.getSideRtpPort(), sipSession.getCallId());
        getRtcpSender().sendRR(ssc,sipSession.getCallId());
        res[0]=doTrying(sipMsg,ssc);
        res[1]= MessageCreator.getCreator(MsgType.PROGRESS183).createMsg(sipSession);
        res[2]=doOK(sipMsg,ssc);
        IcspBeanHolder.getBean(HashedWheelTimer.class).newTimeout(new TalkTimerTask(sipSession.getCallId()),5, TimeUnit.SECONDS);
        return res;
    }




    /*Via: SIP/2.0/UDP 172.168.200.78;rport=5060;received=172.168.200.78;branch=z9hG4bKemByBmt56B38j
        Call-ID: abf0a6b2-91ff-123a-07a8-0050568cd49a
        From: "Extension 78004" <sip:78004@172.168.200.78>;tag=jDg0a8Q2egcge
        To: <sip:78002@172.130.13.31;ob>
                CSeq: 41368608 INVITE
        Content-Length:  0*/
    private String doTrying(SipMsg sipMsg, SipServerContext ssc)
    {
        StringBuilder sb = new StringBuilder();
        sb.append("SIP/2.0 100 Trying").append(MsgEle.LINE_SEPARATOR);
        String[] lines = StringUtils.split(sipMsg.toString(), MsgEle.LINE_SEPARATOR);
        for (String line : lines) {
            if (line.indexOf(MsgEle.VIA) > -1
                    || line.indexOf(MsgEle.FROM) > -1
                    || line.indexOf(MsgEle.CALL_ID) > -1
                    || line.indexOf(MsgEle.CSEQ) > -1) {
                sb.append(line).append(MsgEle.LINE_SEPARATOR);
            }
            else if(line.indexOf(MsgEle.TO) > -1)
            {
                sb.append(line.replaceFirst(RegexUtils.REGEX_EXT2,";")).append(MsgEle.LINE_SEPARATOR);
            }
        }
        sb.append("User-Agent: Robot No1").append(MsgEle.LINE_SEPARATOR);
        sb.append("Content-Length:  0").append(MsgEle.LINE_SEPARATOR);
        sb.append(MsgEle.LINE_SEPARATOR);
        return sb.toString();
    }


    /*Via: SIP/2.0/UDP 172.168.200.78;rport=5060;received=172.168.200.78;branch=z9hG4bKemByBmt56B38j
    Call-ID: abf0a6b2-91ff-123a-07a8-0050568cd49a
    From: "Extension 78004" <sip:78004@172.168.200.78>;tag=jDg0a8Q2egcge
    To: <sip:78002@172.130.13.31;ob>;tag=7b69cbc25bc54a4e8ca261d5d8e875a4
    CSeq: 41368608 INVITE
    Contact: "78002" <sip:78002@172.130.13.31:54685;ob>
    Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
    Content-Length:  0*/
    private String doRinging(SipMsg sipMsg, SipServerContext ssc)
    {
        SipSession session=IcspBeanHolder.getBean(ISipSessionCache.class).get(sipMsg.getCallId());
        StringBuilder sb = new StringBuilder();
        sb.append("SIP/2.0 180 Ringing").append(MsgEle.LINE_SEPARATOR);
        String[] lines = StringUtils.split(sipMsg.toString(), MsgEle.LINE_SEPARATOR);
        for (String line : lines) {
            if (line.indexOf(MsgEle.VIA) > -1
                    || line.indexOf(MsgEle.FROM) > -1
                    || line.indexOf(MsgEle.CALL_ID) > -1
                    || line.indexOf(MsgEle.CSEQ) > -1) {
                sb.append(line).append(MsgEle.LINE_SEPARATOR);
            }
            else if(line.indexOf(MsgEle.ALLOW) > -1)
            {
                sb.append("Contact: <sip:"+session.getTo()+"@"+ ssc.getRunIp()+":"+ssc.getRunPort()+";transport=udp>").append(MsgEle.LINE_SEPARATOR);
                sb.append(line).append(MsgEle.LINE_SEPARATOR);
            }
            else if(line.indexOf(MsgEle.TO) > -1)
            {
                sb.append(line.replaceFirst(RegexUtils.REGEX_EXT2,";")).append(MsgEle.LINE_SEPARATOR);
            }
        }
        sb.append("Content-Length:  0").append(MsgEle.LINE_SEPARATOR);
        sb.append(MsgEle.LINE_SEPARATOR);
        return sb.toString();
    }

    /*
    * Via: SIP/2.0/UDP 172.168.200.78;rport=5060;received=172.168.200.78;branch=z9hG4bKemByBmt56B38j
Call-ID: abf0a6b2-91ff-123a-07a8-0050568cd49a
From: "Extension 78004" <sip:78004@172.168.200.78>;tag=jDg0a8Q2egcge
To: <sip:78002@172.130.13.31;ob>;tag=7b69cbc25bc54a4e8ca261d5d8e875a4
CSeq: 41368608 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Contact: "78002" <sip:78002@172.130.13.31:54685;ob>
Supported: replaces, 100rel, timer, norefersub
Content-Type: application/sdp
Content-Length:   319

v=0 //代表SDP的版本号是0
o=- 3840862401 3840862402 IN IP4 172.130.13.31 //UserA代表这个SDP的发起者是UserA,注意不要跟前面的Kane Zeng搞混淆了；289044526是说这个SDP消息的唯一标识；IN代表是Internet;IP4代表用的是IP4;here.com代表地址。
s=pjmedia //是指流媒体会话的名字叫Session SDP
b=AS:84
t=0 0 //表示这次会话没有超时限制。
a=X-nat:0
m=audio 4002 RTP/AVP 8 101 示这次流媒体传输是通过音频，并且使用了RTP协议，并且使用了4002端口。
c=IN IP4 172.130.13.31
b=TIAS:64000
a=rtcp:4003 IN IP4 172.130.13.31
a=sendrecv
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ssrc:1013002239 cname:249e2b0c11f45dd5
*/
    private String doOK(SipMsg sipMsg,  SipServerContext ssc)
    {
        SipSession session=IcspBeanHolder.getBean(ISipSessionCache.class).get(sipMsg.getCallId());
        int rtcpPort=session.getLocalPort()+11;
        int rtpPort=session.getLocalPort()+10;
        String rtcpIp= ssc.getRunIp();
        StringBuilder sb = new StringBuilder();
        sb.append("SIP/2.0 200 OK").append(MsgEle.LINE_SEPARATOR);
        String[] lines = StringUtils.split(sipMsg.toString(), MsgEle.LINE_SEPARATOR);
        for (String line : lines) {
            if (line.indexOf(MsgEle.VIA) > -1
                    || line.indexOf(MsgEle.FROM) > -1
                    || line.indexOf(MsgEle.CALL_ID) > -1
                    || line.indexOf(MsgEle.CSEQ) > -1) {
                sb.append(line).append(MsgEle.LINE_SEPARATOR);
            }
            else if(line.indexOf(MsgEle.ALLOW) > -1)
            {
                sb.append(line).append(MsgEle.LINE_SEPARATOR);
                sb.append("Contact: <sip:"+session.getTo()+"@"+session.getLocalIp()+":"+session.getLocalPort()+";transport=udp>").append(MsgEle.LINE_SEPARATOR);
                sb.append("Supported: replaces, 100rel, timer, norefersub").append(MsgEle.LINE_SEPARATOR);
                sb.append("Content-Type: application/sdp").append(MsgEle.LINE_SEPARATOR);

            }
            else if(line.indexOf(MsgEle.TO) > -1)
            {
                sb.append(line.replaceFirst(":[0-9]{1,5};",";")).append(MsgEle.LINE_SEPARATOR);
            }
        }
        StringBuilder sbBody=new StringBuilder();
        sbBody.append("v=0").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("o=ROBOT "+ IdUtils.getId()+" 0 IN IP4 "+rtcpIp).append(MsgEle.LINE_SEPARATOR);
        sbBody.append("s=ROBOT").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("b=AS:84").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("t=0 0").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("a=X-nat:0").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("m=audio "+rtpPort+" RTP/AVP 8 101").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("c=IN IP4 "+rtcpIp).append(MsgEle.LINE_SEPARATOR);
        sbBody.append("a=rtcp:"+rtcpPort+" IN IP4 "+rtcpIp).append(MsgEle.LINE_SEPARATOR);
        sbBody.append("a=sendrecv").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("a=rtpmap:8 PCMA/8000").append(MsgEle.LINE_SEPARATOR);
        sbBody.append("a=fmtp:101 0-16").append(MsgEle.LINE_SEPARATOR);

        sb.append("Content-Length:  "+sbBody.length()).append(MsgEle.LINE_SEPARATOR);
        sb.append(MsgEle.LINE_SEPARATOR);
        sb.append(sbBody);
        sbBody.append("a=ssrc:1013002239 cname:249e2b0c11f45dd5").append(MsgEle.LINE_SEPARATOR);
        sb.append(MsgEle.LINE_SEPARATOR);
        return sb.toString();
    }

}
